package top.zhouze.common.util;

import android.util.Log;
import androidx.lifecycle.LifecycleOwner;
import io.reactivex.Maybe;
import io.reactivex.Observable;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import top.zhouze.common.annotation.Subscriber;
import top.zhouze.common.bus.RxBus;
import top.zhouze.common.constant.ThreadMode;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @author 周仄
 * @since 2023/11/29 11:03
 */
public class RxUtil {
    /**
     * 线程调度器
     */
    public static <T> Observable<T> schedulersTransformer(Observable<T> observable) {
        return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
    }

    /**
     * 线程调度器
     */
    public static <T> Single<T> schedulersTransformer(Single<T> observable) {
        return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
    }

    /**
     * 线程调度器
     */
    public static <T> Maybe<T> schedulersTransformer(Maybe<T> observable) {
        return observable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
    }

    public static Disposable[] registerBus(LifecycleOwner obj) {
        List<Disposable> disposables = new ArrayList<>();
        Class<?> clazz = obj.getClass();
        for (Method method : clazz.getDeclaredMethods()) {
            Subscriber subscriber = method.getAnnotation(Subscriber.class);
            if (subscriber != null) {
                Observable<?> observable;
                if (subscriber.isSticky()) {
                    observable = RxBus.getDefault().toObservableSticky(method.getParameterTypes()[0], subscriber.tag());
                    if (subscriber.readOnlyOnce()) {
                        RxBus.getDefault().removeStickyEvent(method.getParameterTypes()[0], subscriber.tag());
                    }
                } else {
                    observable = RxBus.getDefault().toObservable(method.getParameterTypes()[0], subscriber.tag());
                }
                if (Objects.requireNonNull(subscriber.mode()) == ThreadMode.IO) {
                    observable = observable.subscribeOn(Schedulers.io());
                } else {
                    observable = observable.subscribeOn(AndroidSchedulers.mainThread());
                }
                disposables.add(observable
                        .subscribe(data -> {
                            method.setAccessible(true);
                            method.invoke(obj, data);
                        }, err -> Log.w("RxBus err",err)));
            }
        }
        return disposables.toArray(new Disposable[0]);
    }
}

